package com.inspur.edp.common.type.utils;

import com.inspur.edp.common.type.Field;
import com.inspur.edp.common.type.Type;
import com.inspur.edp.common.type.TypeRefer;
import com.inspur.edp.common.type.cache.TypeThreadCache;
import com.inspur.edp.common.type.exception.TypeException;
import com.inspur.edp.common.type.spi.TypeProviderFactory;
import com.inspur.edp.common.type.spi.TypeResourceProvider;

import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @author lizhaorui
 * @date 2025/8/18
 * @description
 */
public class TypeUtil {

    public static String getTypeCode(String fullName) {
        int index = fullName.lastIndexOf(".");
        return fullName.substring(index + 1);
    }

    public static String getTypeUrl(Type type) {
        return getTypeUrl(type.getSource(), type.getTypeId());
    }

    public static String getTypeUrl(TypeRefer typeRefer) {
        return getTypeUrl(typeRefer.getSource(), typeRefer.getTypeId());
    }

    public static String getTypeUrl(String source, String typeId) {
        TypeResourceProvider provider = TypeProviderFactory.getProvider(source);
        if (provider == null) {
            return String.format("%s_%s", source, typeId);
        } else {
            return provider.getUrl(typeId);
        }
    }

    public static TypeRefer parsePath(String source, String typeId, String path) {
        String[] pathItems = path.split("/");
        TypeRefer currentType = new TypeRefer(source, typeId);
        String currentPath = "";
        for (String pathItem : pathItems) {
            currentPath = currentPath + pathItem + "/";
            if (pathItem.equals("[]")) {
                List<TypeRefer> genericTypes = currentType.getGenericTypes();
                if (genericTypes == null || genericTypes.size() == 0) {
                    throw new TypeException(String.format("path %s not is array type ", currentPath));
                }
                return genericTypes.get(0);
            } else {
                Type type = TypeThreadCache.getType(currentType);
                List<Field> fields = type.getFields().stream().filter(new Predicate<Field>() {
                    @Override
                    public boolean test(Field field) {
                        return field.getCode().equals(pathItem);
                    }
                }).collect(Collectors.toList());
                if (fields == null || fields.size() == 0) {
                    throw new TypeException(String.format("parse path %s not exist field %s ", path, pathItem));
                }
                currentType = fields.get(0).getType();
            }
        }
        return currentType;
    }


}